﻿

using Microsoft.AspNetCore.SignalR;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using WHLRDF;
using WHLRDF.Model;

namespace WHLRDF.Socket
{
    
    /// <summary>
    /// SignalR
    /// </summary>
    public class SignalRService : Hub, ISocketService
    {
        private readonly object locker = new object();
        /// <summary>
        /// 用于存储在线的websocket用户
        /// </summary>
        public static List<OnlineUserModel> SocketConnectUsers
        {
            get
            {
                return SocketUsers.SocketConnectUsers;
            }
        }
        public override Task OnConnectedAsync()
        {
            var userModel= SocketConnectUsers.Where(x => (x.ConnectionId == Context.ConnectionId&&x.ConnectionId==x.UserId) ||(x.ConnectionId != x.UserId&&x.UserId == ApplicationEnvironments.DefaultSession.UserId)).FirstOrDefault();
            if (userModel == null)
            {
                if (string.IsNullOrWhiteSpace(ApplicationEnvironments.DefaultSession.UserId))
                {
                    userModel = new OnlineUserModel { ConnectionId = Context.ConnectionId, UserId = Context.ConnectionId, UserName = "游客" };
                }
                else
                {
                    userModel = new OnlineUserModel { ConnectionId = Context.ConnectionId, UserId = ApplicationEnvironments.DefaultSession.UserId, UserName = ApplicationEnvironments.DefaultSession.RealName };
                }
                SocketConnectUsers.Add(userModel);
            }
            else
            {
                userModel.ConnectionId = Context.ConnectionId;
            }
            SendMessage(new SocketMessageModel //，失败时回发用户消息
            {
                SenderId = "Service",
                ReceiverId = Context.ConnectionId,
                SenderName = "系统",
                MessageType = "text",
                Content = Context.ConnectionId
            });
            return base.OnConnectedAsync();
        }


        /// <summary>
        /// 发送给指定用户
        /// </summary>
        /// <param name="userid">接收用户的连接ID</param>
        /// <param name="sendMsg">发送的消息</param>
        public void SendMessage(SocketMessageModel wSMessage)
        {
            // 把消息推送对方（对话框标识，对话框名称，发送者标识，发送者昵称，消息，发送时间）
            if (!Send(wSMessage))
            {
                
                Send(new SocketMessageModel //，失败时回发用户消息
                {
                    SenderId = "Service",
                    ReceiverId = wSMessage.SenderId,
                    SenderName = "系统",
                    MessageType = "text",
                    Content = "用户已下线，消息改为留言" 
                });
            }
        }
       
        /// <summary>
        /// 发送消息
        /// </summary>
        /// <param name="wSMessage">消息对象</param>
        /// <returns></returns>
        public  bool Send(SocketMessageModel wSMessage)
        {
 
            var onlineUser=  SocketConnectUsers.Where(x=>x.ConnectionId==wSMessage.ReceiverId||x.UserId==wSMessage.ReceiverId).FirstOrDefault();
            if (onlineUser!=null)
            {
                AppHttpContext.GetSerivce<IHubContext<SignalRService>>().Clients.Client(onlineUser.ConnectionId).SendAsync("ReceiveMessage", wSMessage);
                return true;
            }
            return false;

        }
        public override Task OnDisconnectedAsync(Exception ex)
        {
            SocketConnectUsers.RemoveAll(x => (x.ConnectionId == Context.ConnectionId && x.ConnectionId == x.UserId) || (x.ConnectionId != x.UserId && x.UserId == ApplicationEnvironments.DefaultSession.UserId));
            return base.OnDisconnectedAsync(ex);

        }

        public Task SendAllExceptMe(string message)
        {
            return Clients.AllExcept(Context.ConnectionId).SendAsync("ReceiveMessage", $"{Context.ConnectionId}: {message}");

        }

        public Task SendToGroup(string groupName, string message)
        {
            return Clients.Group(groupName).SendAsync("ReceiveMessage", $"{Context.ConnectionId}@{groupName}: {message}");

        }

        public async Task JoinGroup(string groupName)
        {
            await Groups.AddToGroupAsync(Context.ConnectionId, groupName);
            await Clients.Group(groupName).SendAsync("ReceiveMessage", $"{Context.ConnectionId}joined {groupName}");

        }

        public async Task LeaveGroup(string groupName)
        {
            await Groups.RemoveFromGroupAsync(Context.ConnectionId, groupName);
            await Clients.Group(groupName).SendAsync("ReceiveMessage", $"{Context.ConnectionId}left {groupName}");
        }

        public Task Echo(string message)
        {
            return Clients.Client(Context.ConnectionId).SendAsync("ReceiveMessage", $"{Context.ConnectionId}: {message}");
        }

    }
}
